我們在實務上難免會遇到需要去限制端點的流量,那 FastAPI 本身並沒有提供這個功能,我們可以使用第三方套件來實作這件事。
而這次要介紹的是 SlowAPI 這個套件,名字剛好跟 FastAPI 相反,這個套件有以下幾個特色:
pip install slowapi
我們直接用 pip 安裝到你的環境即可。
安裝好之後,我們需要在程式碼中,將其載入到 FastAPI 的 app 物件中,所以我們可以直接修改在 main 中:
# main.py
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
limiter = Limiter(key_func=get_remote_address)
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
這邊主要就是實體化一個 limiter,並將其指定給我們的 app.state.limiter
,這樣 FastAPI 才知道用甚麼東西去限制流量。add_exception_handler
是告訴 FastAPI 說,發生 RateLimitExceeded
的錯誤時,要用哪個 handler 去處理。
當我們設定好後我們就可以開始來使用這個限制器:
@app.get("/")
@limiter.limit("3/5 second")
def root(request: Request):
"""
Root
"""
return {"message": "Hello World"}
這裡有幾個點需要注意的:
有一個地方出錯便會導致 limiter 無法生效。
因為這個SlowAPI 的底層是 limit 這個套件,所以他的流量限制字串的解析方法也與 limit 相同:
[count] [per|/] [n (optional)] [second|minute|hour|day|month|year]
像是 5 秒 3 個流量你可以寫成 3/5 second
也可以寫成 3 per 5 second
。
我們在5秒內發了7次請求,可以看到只有前3次成功回傳,其他的請求都被拒絕,直到下一個循環開始才又能成功回傳。
你也可以在 Response body 中看到詳細的錯誤訊息告訴你,這個端點只能允許5秒內有3個成功回應。
今天只是提供一個解決方案,網路上也有其他更好的解法可以搭配 FastAPI,也不一定要把流量限制做在程式端,也可以做在伺服器層都可以。而對於 SlowAPI 想要了解更多進階應用可以看官方文件的範例講解,我們今天的介紹就到這邊。